package com.pphh.demo;

import java.time.Instant;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Please add description here.
 *
 * @author huangyinhuang
 * @date 11/14/2018
 */
public class Monitor {

    private static AtomicInteger total = new AtomicInteger();
    private static AtomicInteger pass = new AtomicInteger();
    private static AtomicInteger block = new AtomicInteger();

    private static Monitor ourInstance = new Monitor();
    private static volatile boolean stop = false;

    private Monitor() {
    }

    public static Monitor getInstance() {
        return ourInstance;
    }

    public void incrementTotal() {
        Monitor.total.incrementAndGet();
    }

    public void incrementPass() {
        Monitor.pass.incrementAndGet();
    }

    public void incrementBlock() {
        Monitor.block.incrementAndGet();
    }

    public void tick() {
        System.out.println("start monitor.");
        Thread timer = new Thread(new TimerTask());
        timer.setName("sentinel-timer-task");
        timer.start();
        Monitor.stop = false;
    }

    public void stop() {
        Monitor.stop = true;
        try {
            System.out.println("wait for monitor to stop.");
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException ignore) {
        }
    }

    static class TimerTask implements Runnable {
        @Override
        public void run() {
            System.out.println("begin to print the statistic of current flow at interval of 1 second...");

            long previousTotal = 0;
            long previousPass = 0;
            long previousBlock = 0;
            while (!stop) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    break;
                }
                long globalTotal = total.get();
                long oneSecondTotal = globalTotal - previousTotal;
                previousTotal = globalTotal;

                long globalPass = pass.get();
                long oneSecondPass = globalPass - previousPass;
                previousPass = globalPass;

                long globalBlock = block.get();
                long oneSecondBlock = globalBlock - previousBlock;
                previousBlock = globalBlock;

                if (!Monitor.stop) {
                    String info = String.format("%s, totoal: %s, pass: %s, block: %s", Instant.now(), oneSecondTotal, oneSecondPass, oneSecondBlock);
                    System.out.println(info);
                }
            }

            System.out.println("the end of printing flow statistic.");
        }

    }

}
